class entity
{
	stringw						Nam;		//entity Name
	IAnimatedMesh				Msh;		//entity Mesh
	IAnimatedMeshSceneNode      Nde;		//entity Scenenode
	cSkeleton					Ani;		//entity Animator
	vector3df					Epd;		//entity Collision Ellipsoid
	vector3df					Vlc;		//entity Velocity
	float						F0V;		//entity Field of View
	float						Dst			//entity View Distance
	stringw						Ste;		//Primary entity State
	stringw						Evt;		//Secondary entity State
	float						Hth;		//entity Health
	stringw						Itm[][];	//entity Item Name, selected Item Slot
	stringw						Wpn[][];	//entity Weapon Name, selected Weapon Slot
	int							Ani[][];	//Animation: First Frame, Last Frame
	bool						Lnd;		//Land Flag

protected:
	aabbox3df list				PthNde;		//entity Path Node
	aabbox3df list				ClsPth;		//entity Closed Paths
	aabbox3df list				OpnPth;		//entity Open Paths
	line3df						Pth[];		//entity Path Spline
	vector3df					Dsp;		//Displacement from Last Position
	vector3df					LstPos;		//Last Position
	triangle3df					Tri;		//Triangle Output from Collision
	int							Fll;		//entity is Falling
	int							VisRng;		//Visual Range Minimum
	int							ActRng;		//Active Range Minimum
	int							IntRng;		//Interactive Range Minimum
	
	virtual entity( stringw, IAnimatedMesh, ISceneNode, vector3df, stringw, stringw, float, stringw[][], stringw[][] );
	Update( profile Nfo )
	{
		map	Map	= Nfo.Lineup::first();	//Map Listing

		switch( Mde )
		{
			case "Ignore":
			case "Follow":
				//Target Nearest Friend
				void	Trg;		//Nearest Target
				float	OfS;		//Offset Distance
				float	LstDst;		//Last Distance

				for each( entity Ent in entity entity::Cnt())
				{
					if(	Ent.Nde.getPosition().getDistanceFrom( this->Nde.getPosition()) < LstDst )
					{
						OfS	= Ent.Nde.getPosition().getDistanceFrom( this->Nde.getPosition());

						switch( typeid( Trg ).name())
							case "entity":
								Trg	= entity( Ent );
								//Distance
								if( OfS > 5 ) Search( Sgt, NULL, Pth );
								if( OfS < Dst ) Move( Spd );
								
								//Follow Entity

								//Check Portal Child Nodes
								break;

							case "prop":
								Trg = prop( Ent );
								//Find Prop

								break;

							case "user":
								Trg	= user( Ent );
								//Follow User
								break;

							case "collectable":
								Trg = collectable( Ent );
								//Collect Item
								break;

							case "portal":
								Trg = portal( Ent );
								break;

						this->Pth	= NULL;
						this->Pth[0].setLineFromLineVects( this->Nde.getPosition(), Trg );
						LstDst		= Ent.Nde.getPosition().getDistanceFrom( this->Nde.getPosition());
					}
				}
				break;

			case "Lead":
				break;
		}

		//State
		switch( Ste )
		{
			case "Walk":
				//Logic
				if( Pth )
				{
					//Follow Direction of Path Spline
					Move( Dir, Spd );
					Search( [backdrop, entity, prop], NULL, NULL );
				}

				//Animation
				
				//Sound
				//Server
				break;

			case "Run":
				//Logic
				if( Pth )
				{
					//Follow Direction of Path Spline
					Move( Spd );
					Search( [backdrop, entity, prop], NULL, NULL );
				}
				break;

			case "Crawl":
				break;
			case "Fall":
				break;
			case "Jump":
				break;
			case "Dead":
				break;
			default "Stand":
				break;
		}

		//Event
		switch( Evt )
		{
			case "Attack":
				IAnimatedMeshSceneNode( Trg );
				break;
			case "Block":
				break;
			case "Hurt":
				break;
			case "Die":
				break;
			case "Disappear":
				break;
			default "Appear":
				break;
		}
	}
	Search( stringw ESgt[], void ETrg, aabbox3df EPrt )
	{
		matrix4f	M;
		map			Map		= map::Cnt::first();	//map Node
		stringw		Sgt[]	= ESgt;					//Search Sight Parameter
		void		Trg		= ETrg;					//Search Target
		aabbox3df	Prt		= EPrt;					//Search Portal?
		
		
		//Find shortest Path to Target
		vector3d	Nrm = entity( Trg ).Nde.getPosition() - ( this->Nde.getPosition()).Normalize();
		this->Pth->setLine( this->Nde.getPosition(), Trg().Nde.getPosition());

		Map.Slc();
		if(	Map.Slc.getTriangles( Pth[0] )
		{
			Pth[0]( Pth[Pth.Length - 1].getEnd(), Col.getCollisionResultPosition( Map.Slc(), this->Nde.getPosition(), Epd, Nrm, this->Tri(), null, 0, vector3df<s32>( 0, Nrm.getLength(), 0 )));
		}

		this->Nde.getPosition().getDistanceFrom( this->Pth[0].getEnd());
		
		//Find Cost of Path
		for( int N; 1 to 8 )
		{
			if(	Map.Slc.getTriangles( line3df( this->Nde.getPosition(), Nrm()), M )
			{
				
				//Find Height/Interaction/Hazards
				Map.Slc.getTriangles( line3d( Pth[0].end() + vector3d( 0, 999, 0 ), Pth[0].end());
				for each( prop P in aabbox3d Pth[0].end().getPosition())
				for each( backdrop B in aabbox3d Pth [
				//Set Path
				this->Pth.Cnt::push_front( line3df( Nrm, Trg ));
				break;
			}
			else
			{
				//Try Another Direction
				Nrm.rotateXZBy( 45 );
			}
		}
	}
	Move( float Dir, float Spd )
	{
		//Walk Along Path
		if( this->Pth.First().isPointBetweenStartAndEnd())
		{
			//Find Direction of Path
			line3df( this->Pth.First()).getend();
		};
	}
	Jump( float Str )
	{
		//Jump
		if(	Lnd == true &&
			Ste == "Stand" ||
			Ste == "Walk" ||
			Ste == "Crouch" ||
			Ste == "Crawl" )
		{
			//Physics
			Vlc.PlusEq( vector3df<s32>( 0, 7, 0 ))	;	//* Incomplete, Could use an Angle to calculate the Velocity Vector

			//Logic
			Ste	= "Jump";
		}

		//Flip
		else if( Ste == "Jump" )
		{
			//Physics
			Vlc.PlusEq( vector3df<s32>( 0, 5, 0 ));	//* Incomplete, Could use an Angle to calculate the Velocity Vector

			//Logic
			Ste	= "Flip";
		}

		//Leap
		else if( Lnd == false && Ste == "Run" )
		{
			//Physics
			matrix4	M;
			vector3df	Frc	= vector3df<s32>( 0, 7, 5 );

			M.setRotationDegrees( Nde.GetRotation());	//* Incomplete, Could use an Angle to calculate the Velocity Vector
			M.transformVect( Frc );
			this->Vlc.PlusEq( Frc );

			//Logic
			Ste	= "Leap";
		}

		//Spring
		else if( Ste == "Climb" ||
			SprTim > 0 &&
			Ste == "Jump" )
		{
			//Physics
			matrix4	M;
			vector3df	Frc	= vector3df<s32>( 0, 5, 7 );

			Nde.SetRotation( Nde.GetRotation().Minus( vector3df<s32>( 180, 0, 0 )));
			M.setRotationDegrees( Nde.GetRotation());	//* Incomplete, Could use an Angle to calculate the Velocity Vector
			M.transformVect( Frc );
			Vlc.setEq( Frc );

			//Logic
			Ste		= "Spring";
			SprTim	= 0;
		}

		//Lift
		else if( Ste == "Hang" ||
			Ste == "Climb" )
		{
			//Physics
			//Logic
		}
	}
	Glide( float Spd )
	Land()
	{

	}
	Collide( void Bdy )
	{
	}
	Climb( float Spd )
	Use( void Bdy )
	{
	}
	ActionPri()
	{
	}
	ActionSec()
	{
	}
	Hurt( float Dmg )
	Die()
	{
		//Disappear
		//Animate 30 F/s
		//Sound
		//Logic
	};
	virtual ~entity();

private:
	list				Cnt;	//List of Entities
	ITriangleselector	Slc;	//Triangle selector
};
entity::entity( stringw Nam, IAnimatedMesh Msh, ISceneNode Nde, vector3df Epd )
entity::~entity()
{
		this->Nde.Remove();
		this->Msh.Remove();
		entity::Cnt::erase( this );

		return this;
};
class friendly : public entity
{
public:
	stringw			Mde;	//A.I. Mode
	list aabbox3df	PthNde;	//entity Path Node
	list aabbox3df	ClsPth;	//entity Closed Paths
	list aabbox3df	OpnPth;	//entity Open Paths
	list			Pth;	//entity Path Spline

	friendly( stringw Nam, IAnimatedMesh Msh, ISceneNode Nde, vector3df Epd, stringw Ste, stringw Evt, float Hth, stringw Itm[][], stringw Wpn[][], stringw Mde, stringw PthNde )
	{
		//Client
		friendly::Cnt::push_back( this );

		//Server
		
		return this;
	}
	Update()
	{
		//Wave
		//for( int Millisecond; Start to End; Timing ) Event;
		//if( trigger ) Event;

		map	Map	= info->Lineup::First;

		//Mode
		switch( Mde )
		{
			case "Follow":
				//Target Nearest Friend
				entity	Trg;		//Nearest Target
				float	LstDst;		//Last Distance

				for each( entity Ent in entity entity::Cnt())
				{
					if(	Ent.Nde.getPosition().getDistanceFrom( this->Nde.getPosition()) < LstDst )
					{
						Trg			= Ent;
						Pth	= null;
						Pth[0].setLineFromLineVects( this->Nde.getPosition(), Trg );
						LstDst		= Ent.Nde.getPosition().getDistanceFrom( this->Nde.getPosition());
					}
				}

				matrix4f	M;

				//Find shortest path to Target
				vector3df	Nrm = entity( Trg ).Nde.getPosition().Minus( this->Nde.getPosition()).Normalize().MultVect( vector3df<s32>( LstDst, 0, LstDst ));

				if(	Map.Slc.getTrianglesOnLine( Pth[Pth.Length - 1] )
				{
					Pth[Pth.Length]( Pth[Pth.Length - 1].getEnd(), Col.getCollisionResultPosition( Map.Slc(), this->Nde.getPosition(), Epd, Nrm, this->Tri(), null, 0, vector3df<s32>( 0, Nrm.getLength(), 0 )));
				}

				this->Nde.getPosition().getDistanceFrom( this->Pth[0].getEnd());

				//Find Cost of Path
				for( int N; 1 to 8 )
				{
					if(	Map.Slc.getTrianglesOnLine( line3df()( this->Nde.getPosition(), Nrm()), M )
					{
						//Set Path
						Pth[Pth.Length - 1] = line3df( Nrm, Trg );
						break;
					}
					else
					{
						Nrm.rotateXZBy( 45 );
					}
				}
				break;

			case "Lead":
				break;
			default "Ignore":
				break;
		}

		//State
		switch( Ste )
		{
			case "Walk":
				break;
			case "Run":
				break;
			case "Crawl":
				break;
			case "Fall":
				break;
			case "Jump":
				break;
			case "Dead":
				break;
			default "Stand":
				break;
		}

		//Event
		switch( Evt )
		{
			case "Attack":
				break;
			case "Block":
				break;
			case "Hurt":
				break;
			case "Die":
				break;
			case "Disappear":
				break;
			default "Appear":
				break;
		}
	};
	Move()
	{
	};
	Jump()
	{
	};
	Glide( float spd );
	Land();
	Collide( void Body )
	{
	};
	Use( void Body )
	{
	};
	ActionPri()
	{
	};
	ActionSec()
	{
	};
	Hurt();
	Die();
	~friendly()
	{
		this->Nde.Remove();
		this->Msh.Remove();

		entity::Cnt.erase( this );
		return this;
	};

private:
	list	Cnt;	//List of friends
};

class enemy : public entity
{
public:
	stringw			Mde;	//A.I. Mode
	list aabbox3df	PthNde;	//entity Path Node
	list aabbox3df	ClsPth;	//entity Closed Paths
	list aabbox3df	OpnPth;	//entity Open Paths
	list			Pth;	//entity Path Spline

	enemy( stringw Nam, IAnimatedMesh Msh, ISceneNode Nde, vector3df Epd, stringw Ste, stringw Evt, float Hth, stringw Itm[][], stringw Wpn[][] )
	{
		//Client
		entity::Cnt::push_back( this );

		//Server
		
		return this;
	};

	Update()
	{
	};

	Move()
	{
	};

	Jump()
	{
	};

	Glide( float spd )
	{
	};

	Land()
	{
	};

	Collide( void Body )
	{
	};

	Use( void Body )
	{
	};

	ActionPri()
	{
	};

	ActionSec()
	{
	};

	Hurt( float Dmg ){};

	Die()
	{
	};

	~enemy()
	{
		this->Nde.Remove();
		this->Msh.Remove();

		entity::Cnt.erase( this );
		return this;
	}
};
